package com.taobao.snowsnow.web;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.tree.DefaultElement;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.taobao.snowsnow.hibernate.pojo.Address;
import com.taobao.snowsnow.hibernate.pojo.Contact;
import com.taobao.snowsnow.hibernate.pojo.Express;
import com.taobao.snowsnow.hibernate.pojo.ExpressFieldPosition;
import com.taobao.snowsnow.hibernate.pojo.ExpressPage;
import com.taobao.snowsnow.hibernate.pojo.Trade;
import com.taobao.snowsnow.hibernate.service.ExpressService;
import com.taobao.snowsnow.hibernate.service.TradeService;
import com.taobao.snowsnow.hibernate.temp.JsonBean;
import com.taobao.snowsnow.taobao.Logistics;
import com.taobao.snowsnow.taobao.PrintKd;
import com.taobao.snowsnow.taobao.TaoBaoUtil;
import com.taobao.snowsnow.util.Util;

public class ExpressAction extends ActionSupport {

	private static final long serialVersionUID = 5036065203830685703L;
	
	private Express express;
	private ExpressFieldPosition fieldPostion;
	private ExpressPage expressPage;
	
	private ExpressService expressService;
	private TradeService tradeService;
	
	private String expressCode;
	private Boolean mutilTids;
	private Long tid;
	private Long[] tids;
	private String outSid;
	
	private InputStream inputStream;
	
	/**
	 * 打印快递单
	 * @return
	 * 			打印结果
	 * @throws Exception
	 */
	public String printExpress() {
		
		try {
			expressCode = new String(expressCode.getBytes("utf8"), "utf8");
			
			// 如果是打印多订单
			if(mutilTids) {
				for(long l : tids) {
					printTid(l);
				}
			} 
			// 打印单张订单
			else {
				// 订单编号不为空的话,就根据订单打印
				if(tid != null) {
					printTid(tid);
				} 
				// 否则根据表单打印
				else if(expressCode != null) {
					express = expressService.findByName(expressCode).get(0);
					new PrintKd(express, expressPage);
				}
			}
			
			inputStream = new ByteArrayInputStream(new String("ok").getBytes());
			return SUCCESS;
		} catch (Exception e) {
			inputStream = new ByteArrayInputStream(new String("error: " + e.toString()).getBytes());
			return SUCCESS;
		}
	}
	
	private void printTid(Long t) {
		express = expressService.findByName(expressCode).get(0);
		Trade trade = tradeService.findByTid(t);
		setExpressPageFromTrade(trade);
		new PrintKd(express, expressPage);
	}
	
	public String initPrintExpress() {
		List<Express> expressList = expressService.findAll();
		expressPage = Util.getMyleftShopperTemplates();
		
		ActionContext .getContext().getSession().put("expressPage", expressPage);
		ActionContext .getContext().getSession().put("expressList", expressList);
		return SUCCESS;
	}

	/**
	 * <p>设置打印页面
	 * @param trade
	 */
	private void setExpressPageFromTrade(Trade trade) {
		Contact cnt = trade.getPeople().getContacts().get(0);
		Address address = cnt.getAddresses().get(0);
		expressPage = Util.getMyleftShopperTemplates();
		
		expressPage.setReceiverName(cnt.getName());
		expressPage.setReceiverCompany(trade.getPeople().getTaobaoId());
		StringBuffer buffer = new StringBuffer();
		
		if(address.getState() != null)
			buffer.append(address.getState().getName());
		
		if(address.getCity() != null) {
			expressPage.setDestinationCity(address.getCity().getName());
			buffer.append(address.getCity().getName());
		}
		
		if(address.getDistrict() != null)
			buffer.append(address.getDistrict().getName());
		
		buffer.append(address.getAddress());
		
		expressPage.setReceiverAddress(buffer.toString());
		
		buffer = new StringBuffer();
		
		if(cnt.getMobile1() != null)
			buffer.append(cnt.getMobile1() + " ");
		
		if(cnt.getHousePhone() != null)
			buffer.append(cnt.getHousePhone() + " ");
		
		
		expressPage.setReceiverPhone(buffer.toString());
	}

	public String createExpress() {
		try {
			express.setExpressfieldposition(fieldPostion);
			expressService.saveOrUpdate(express);
			
			inputStream = new ByteArrayInputStream(new String("ok").getBytes());
			return SUCCESS;
		} catch (Exception e) {
			inputStream = new ByteArrayInputStream(e.toString().getBytes());
			return SUCCESS;
		}
	}
	
	public String editExpress() {
		express = expressService.findById(express.getId());
		
		ActionContext .getContext().getSession().put("express", express);
		return SUCCESS;
	}
	
	/**
	 * <p>Copy快递
	 * @return
	 */
	public String copyExpress() {
		
		try {
			Express older = expressService.findById(express.getId());
			
			Express newer = older.clone();
			newer.setExpressfieldposition(older.getExpressfieldposition().clone());
			expressService.create(newer);
			
			inputStream = new ByteArrayInputStream(new String("ok").getBytes());
			return SUCCESS;
		} catch (Exception e) {
			inputStream = new ByteArrayInputStream(e.toString().getBytes());
			return SUCCESS;
		}
	}
	
	public String deleteExpress() {
		try {
			express = expressService.findById(express.getId());
			expressService.remove(express);
			
			inputStream = new ByteArrayInputStream(new String("ok").getBytes());
			return SUCCESS;
		} catch (Exception e) {
			inputStream = new ByteArrayInputStream(new String("error: " + e.toString()).getBytes());
			return SUCCESS;
		}
	}
	
	/**
	 * <p>查找全部的快递
	 * @return
	 * @throws Exception
	 */
	public String findAllExpress() throws Exception {
		List<Express> expressList = expressService.findAll();
		ActionContext .getContext().getSession().put("expressList", expressList);
		return SUCCESS;
	}
	
	/**
	 * <p>跟踪快递单
	 * @return
	 * 			快递单轨迹信息
	 */
	@SuppressWarnings("unchecked")
	public String expressTrace() {
		
		try {
			String result = Logistics.traceSearch(tid);
			
			String out_sid = null;
			String tid = null;
			String company_name = null;
			
			Document document = DocumentHelper.parseText(result);
			List<DefaultElement> list = document.selectNodes("//logistics_trace_search_response");
			for (DefaultElement df : list) {
				out_sid = df.elementText("out_sid");
				tid = df.elementText("tid");
				company_name = df.elementText("company_name");
			}
			
			JSONObject output_json = null;
			
			JsonBean bean = null;
			List<JsonBean> l = new ArrayList<JsonBean>();
			
			
			if(!result.contains("该订单无流转信息")) {
				
				for (DefaultElement df : list) {
					
					Element trace_list = df.element("trace_list");
					
					for(DefaultElement transit_step_info : (List<DefaultElement>) trace_list.elements("transit_step_info")) {
						bean = new JsonBean();
						bean.setContext(transit_step_info.elementText("status_desc"));
						bean.setTime(transit_step_info.elementText("status_time"));
						l.add(bean);
					}
				}
				Collections.reverse(l);
			} else {
				
				if(out_sid != null) {
					Map<String, String> map = new HashMap<String, String>();
					map.put("STO", "shentong");
					map.put("申通E物流", "shentong");
					map.put("SF", "shunfeng");
					map.put("顺丰速运", "shunfeng");
					map.put("SFHK", "shunfeng");
					map.put("ZJS", "zhaijisong");
					map.put("宅急送", "zhaijisong");
					
					String express = map.get(company_name);
					
					String query_url = "http://baidu.kuaidi100.com/query?type=:express&postid=:outSid";
					
					query_url = query_url.replaceFirst(":express", express);
					query_url = query_url.replaceFirst(":outSid", out_sid);
					
					// 要解析的json
					String json = TaoBaoUtil.getResult(query_url);
					
					JSONObject jsonObject = JSONObject.fromObject(json);
					JSONArray array = jsonObject.getJSONArray("data");
					
					for(int i = 0; i < array.size(); i++) {
						bean = new JsonBean();
						bean.setTime((String) array.getJSONObject(i).get("time"));
						bean.setContext((String) array.getJSONObject(i).get("context"));
						l.add(bean);
					}
				}
			}
			
			if(list.size() != 0 && out_sid != null) 
				output_json = new JSONObject();
			
			if(output_json != null) {
				// 要输出的json
				output_json.put("tid", tid);
				output_json.put("out_sid", out_sid);
				output_json.put("company_name", company_name);
				JSONArray ja = JSONArray.fromObject(l);
				output_json.put("data", ja);
				inputStream = new ByteArrayInputStream(output_json.toString().getBytes("utf8"));
			} else
				inputStream = new ByteArrayInputStream("empty".getBytes());
			
			return SUCCESS;
		} catch (Exception e) {
			inputStream = new ByteArrayInputStream(("error: " + e.toString()).getBytes());
			return SUCCESS;
		}
	}
	
	public Express getExpress() {
		return express;
	}

	public void setExpress(Express express) {
		this.express = express;
	}

	public ExpressFieldPosition getFieldPostion() {
		return fieldPostion;
	}

	public void setFieldPostion(ExpressFieldPosition fieldPostion) {
		this.fieldPostion = fieldPostion;
	}

	public ExpressService getExpressService() {
		return expressService;
	}

	public void setExpressService(ExpressService expressService) {
		this.expressService = expressService;
	}

	public TradeService getTradeService() {
		return tradeService;
	}

	public void setTradeService(TradeService tradeService) {
		this.tradeService = tradeService;
	}

	public InputStream getInputStream() {
		return inputStream;
	}

	public void setInputStream(InputStream inputStream) {
		this.inputStream = inputStream;
	}

	public ExpressPage getExpressPage() {
		return expressPage;
	}

	public void setExpressPage(ExpressPage expressPage) {
		this.expressPage = expressPage;
	}

	public String getExpressCode() {
		return expressCode;
	}

	public void setExpressCode(String expressCode) {
		this.expressCode = expressCode;
	}

	public Long getTid() {
		return tid;
	}

	public void setTid(Long tid) {
		this.tid = tid;
	}

	public Long[] getTids() {
		return tids;
	}

	public void setTids(Long[] tids) {
		this.tids = tids;
	}

	public Boolean isMutilTids() {
		return mutilTids;
	}

	public void setMutilTids(Boolean mutilTids) {
		this.mutilTids = mutilTids;
	}

	public String getOutSid() {
		return outSid;
	}

	public void setOutSid(String outSid) {
		this.outSid = outSid;
	}
}
